<?php
// +----------------------------------------------------------------------
// | QSCMS
// +----------------------------------------------------------------------
// | Copyright (c)  2025 https://www.qqss.net All rights reserved.
// +----------------------------------------------------------------------
// | Licensed QSCMS is not free software, commercial use must purchase official license from official website to avoid unnecessary legal disputes.
// +----------------------------------------------------------------------
// | Author: Contract 990504246@qq.com
// +----------------------------------------------------------------------

namespace app\adminapi\controller\plugin;

/**
 * 插件下载管理控制器
 */
class Download extends Base
{

    /**
     * 下载并安装插件
     */
    public function downloadAndInstall()
    {
        try {
            $request    = request();
            $pluginId   = $request->post('plugin_id');
            $pluginName = $request->post('plugin_slug');
            $isUpgrade  = $request->post('is_upgrade', false); // 升级标识
            $type       = $request->post('type', 'plugin'); // 默认为plugin类型

            if (empty($pluginId)) {
                return $this->error('插件ID不能为空');
            }

            // 获取插件信息
            $pluginInfo = $this->getPluginInfo($pluginId);
            if (!$pluginInfo) {
                return $this->error('插件不存在');
            }

            // 统一从后端获取token
            $token = $this->getUserToken();

            // 检查是否为免费插件或已购买
            if ($pluginInfo['price'] > 0) {
                // 付费插件需要登录和购买验证
                if (empty($token)) {
                    return $this->error('付费插件需要先登录', 401);
                }
            }
            // 获取下载链接（免费插件可能不需要token）
            $downloadInfo = $this->getDownloadLink($pluginId, $token, $type);

            // 下载插件文件
            $downloadResult = $this->downloadPluginFile($downloadInfo);

            // 安装或升级插件
            $installResult = $this->extractAndInstallPlugin($pluginName, $downloadResult['file_path'], $isUpgrade);

            $message = $isUpgrade ? '插件升级成功' : '插件安装成功';
            return $this->success($message, $installResult);
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 获取已购买的插件列表
     */
    public function getPurchasedPlugins()
    {
        try {
            $token = $this->getUserToken();

            if (empty($token)) {
                return $this->error('请先登录', []);
            }

            $plugins = $this->getPurchasedPluginsFromMain($token);
            return $this->success('获取成功', $plugins);
        } catch (\Exception $e) {
            return $this->error('获取失败：' . $e->getMessage());
        }
    }

    /**
     * 安装插件 本地安装 todo
     */
    public function installPlugin()
    {
        try {
            $pluginId = input('plugin_id');
            $filePath = input('file_path');

            if (empty($pluginId) || empty($filePath)) {
                return $this->error('参数不完整');
            }

            // 解压并安装插件
            $installResult = $this->extractAndInstallPlugin($pluginId, $filePath);

            return $this->success('安装成功', $installResult);
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 获取本地已安装插件列表
     */
    public function getInstalledPlugins()
    {
        try {
            $pluginDir        = base_path() . '/plugins/';
            $installedPlugins = [];

            if (is_dir($pluginDir)) {
                $dirs = scandir($pluginDir);
                foreach ($dirs as $dir) {
                    if ($dir !== '.' && $dir !== '..' && is_dir($pluginDir . $dir)) {
                        $configFile = $pluginDir . $dir . '/config.json';
                        if (file_exists($configFile)) {
                            $config = json_decode(file_get_contents($configFile), true);
                            if ($config) {
                                $installedPlugins[] = [
                                    'id'          => $dir,
                                    'name'        => $config['name'] ?? $dir,
                                    'version'     => $config['version'] ?? '1.0.0',
                                    'description' => $config['description'] ?? '',
                                    'status'      => $config['status'] ?? 'disabled'
                                ];
                            }
                        }
                    }
                }
            }

            return $this->success('获取成功', $installedPlugins);
        } catch (\Exception $e) {
            return $this->error('获取失败：' . $e->getMessage());
        }
    }

    /**
     * 从main项目获取下载链接
     */
    private function getDownloadLink($pluginId, $token, $type = 'plugin')
    {
        $url    = $this->getMainApiUrl('/api/download/plugin');
        $params = [
            'plugin_id' => $pluginId,
            'type'      => $type,
            'token'     => $token
        ];

        $response = httpRequest($url, $params, 'POST');
        if ($response['code'] != 1) {
            throw new \Exception($response['msg'] ?? '获取下载链接失败');
        }

        return $response['data'];
    }

    /**
     * 下载插件文件
     */
    private function downloadPluginFile($downloadInfo)
    {
        $downloadUrl = $downloadInfo['download_url'];
        $fileName    = $downloadInfo['file_name'];

        // 创建下载目录
        $downloadDir = runtime_path() . '/downloads/';
        if (!is_dir($downloadDir)) {
            mkdir($downloadDir, 0755, true);
        }

        $filePath = $downloadDir . $fileName;

        // 下载文件
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL            => $downloadUrl,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT        => 300, // 5分钟超时
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_FOLLOWLOCATION => true,
        ]);

        $fileContent = curl_exec($ch);
        $httpCode    = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error       = curl_error($ch);
        curl_close($ch);

        if ($error) {
            throw new \Exception('下载失败：' . $error);
        }

        if ($httpCode !== 200) {
            throw new \Exception('下载失败，HTTP状态码：' . $httpCode);
        }

        // 保存文件
        if (file_put_contents($filePath, $fileContent) === false) {
            throw new \Exception('保存文件失败');
        }

        return [
            'file_path' => $filePath,
            'file_size' => filesize($filePath)
        ];
    }

    /**
     * 从main项目获取已购买插件列表
     */
    private function getPurchasedPluginsFromMain($token)
    {
        $url = $this->getMainApiUrl('/api/plugin/purchased');

        $params = ['token' => $token];

        $response = httpRequest($url, $params);

        if ($response['code'] !== 1) {
            throw new \Exception($response['msg'] ?? '获取已购买插件失败');
        }

        return $response['data'] ?? [];
    }

    /**
     * 解压并安装插件
     */
    private function extractAndInstallPlugin($pluginName, $filePath, $isUpgrade = false)
    {
        if (!file_exists($filePath)) {
            throw new \Exception('插件文件不存在');
        }

        $pluginDir = base_path() . '/plugins/';
        $targetDir = $pluginDir . $pluginName . '/';

        // 创建插件目录
        if (!is_dir($pluginDir)) {
            mkdir($pluginDir, 0755, true);
        }

        // 如果是升级，备份当前版本
        $backupDir = null;
        if ($isUpgrade && is_dir($targetDir)) {
            $backupDir = $pluginDir . $pluginName . '_backup_' . date('YmdHis') . '/';
            rename($targetDir, $backupDir);
        }

        try {
            // 解压文件
            $zip = new \ZipArchive();
            if ($zip->open($filePath) === TRUE) {
                $zip->extractTo($pluginDir);
                $zip->close();

                // 删除下载的压缩文件
                unlink($filePath);

                // 检查插件配置文件
                $configFile = $targetDir . 'info.ini';
                if (!file_exists($configFile)) {
                    throw new \Exception('插件配置文件不存在');
                }

                $config = parse_ini_file($configFile);
                if (!$config) {
                    throw new \Exception('插件配置文件格式错误');
                }

                // 如果是升级，执行升级SQL
                if ($isUpgrade) {
                    $this->executeUpgradeSQL($targetDir);
                    // 删除备份目录
                    if ($backupDir && is_dir($backupDir)) {
                        $this->deleteDirectory($backupDir);
                    }
                    $status = 'upgraded';
                } else {
                    // 新安装时设置插件状态为禁用
                    (new \app\common\plugin\PluginManager())->disablePlugin($config['name']);
                    $status = 'disabled';
                }

                return [
                    'name'         => $config['name'],
                    'version'      => $config['version'] ?? '1.0.0',
                    'install_path' => $pluginDir,
                    'status'       => $status
                ];
            } else {
                throw new \Exception('解压插件文件失败');
            }
        } catch (\Exception $e) {
            // 如果是升级且失败，恢复备份
            if ($isUpgrade && $backupDir && is_dir($backupDir)) {
                if (is_dir($targetDir)) {
                    $this->deleteDirectory($targetDir);
                }
                rename($backupDir, $targetDir);
            }
            throw $e;
        }
    }

    /**
     * 获取插件信息
     */
    private function getPluginInfo($pluginId)
    {
        // 调用main项目API获取插件信息
        $url = $this->getMainApiUrl('/api/service/plugin/') . $pluginId;

        $response = httpRequest($url);
        if ($response && isset($response['code']) && $response['code']) {
            return $response['data'];
        }
        return null;
    }

    /**
     * 执行升级SQL
     */
    private function executeUpgradeSQL($pluginDir)
    {
        $upgradeFile = $pluginDir . 'upgrade.sql';
        if (!file_exists($upgradeFile)) {
            return; // 没有升级SQL文件，跳过
        }

        try {
            $sql = file_get_contents($upgradeFile);
            if (empty(trim($sql))) {
                return;
            }

            // 分割SQL语句
            $statements = array_filter(array_map('trim', explode(';', $sql)));

            foreach ($statements as $statement) {
                if (!empty($statement)) {
                    \support\Db::statement($statement);
                }
            }

            // 执行完成后删除升级SQL文件
            unlink($upgradeFile);

        } catch (\Exception $e) {
            throw new \Exception('执行升级SQL失败：' . $e->getMessage());
        }
    }

    /**
     * 递归删除目录
     */
    private function deleteDirectory($dir)
    {
        if (!is_dir($dir)) {
            return;
        }

        $files = array_diff(scandir($dir), ['.', '..']);
        foreach ($files as $file) {
            $path = $dir . '/' . $file;
            if (is_dir($path)) {
                $this->deleteDirectory($path);
            } else {
                unlink($path);
            }
        }
        rmdir($dir);
    }


}
